
/* Generated by Interface Builder */

#import "Controller.h"
#import "EnvelopeView.h"
#import <appkit/Application.h>
#import <appkit/Panel.h>
#import <appkit/Button.h>
#import <appkit/ButtonCell.h>
#import <appkit/Cell.h>
#import <appkit/ActionCell.h>
#import <appkit/Matrix.h>
#import <appkit/View.h>
#import <appkit/Form.h>
#import <appkit/Listener.h>
#import <appkit/PopUpList.h>
#import	<appkit/NXSplitView.h>
#import	<objc/List.h>
#import <stdlib.h>
#import <ctype.h>
#import <math.h>

extern NXDefaultsVector envelopeDefaults;

@implementation Controller

- appDidInit:sender
{
	lastDeleted=NULL;
	theEnvelope=NULL;
	myListener=[NXApp appListener];
	[myListener setServicesDelegate: self];
    [theWindow makeKeyAndOrderFront: self];
	NXRegisterDefaults("EnvelopeEd",envelopeDefaults);
	[self addEnvelope: self];
	return self;
}

- infoPanel:sender
{
    if(!infoPanel) {
        [NXApp loadNibSection:"Info.nib" owner:self];
    }
    [infoPanel makeKeyAndOrderFront:sender];
    return self;
}

- helpPanel:sender
{
    if(!helpPanel) {
        [NXApp loadNibSection:"Info.nib" owner:self];
    }
    [helpPanel makeKeyAndOrderFront:sender];
    return self;
}

//===================================================================
// Operations on Envelopes
//===================================================================

- addEnvelope:sender
{
	id old;
	
	NXRect * theFrame;
	theFrame = malloc (sizeof (NXRect));
	[theSplitView getFrame: theFrame];
	old=theEnvelope;
	if (old!=NULL) [old dim];
	theEnvelope=[[EnvelopeView alloc] initFrame: theFrame];
	[theEnvelope controllerIs: self];
	[theSplitView addSubview: theEnvelope];
	[theSplitView adjustSubviews];
	[theSplitView display];
	[theWindow makeFirstResponder: theEnvelope];
	if (old!=NULL && [theLinkX state]==1) 
		[self broadcastXLimitsOf: old];
	free (theFrame);
    return self;
}

- removeEnvelope:sender
{
	id views;
	unsigned int lastIndex;
	
	if (theEnvelope!=NULL) {
		lastIndex=[[theSplitView subviews] 
			indexOf: theEnvelope];				// where is on the subview list?
		lastDeleted=[theEnvelope copy];			// remember last envelope...
		[theEnvelope removeFromSuperview];		// ...but delete it from the window!
		views=[theSplitView subviews];
		if ([views count]==0)					// define pointer to new envelope
			theEnvelope=NULL;
		else {
			if ((theEnvelope=[views objectAt: lastIndex])==NULL)
				theEnvelope=[views objectAt: 0];
		}
		if (theEnvelope!=NULL)
			[theWindow makeFirstResponder: theEnvelope];
		
		[theSplitView adjustSubviews];			// display new split view
		[theSplitView display];
	}
	return self; 
}

- unRemoveEnvelope:sender
{
	id old;
	
	if (lastDeleted!=NULL) {					// only if previous delete
		[theSplitView addSubview: lastDeleted];
		old=theEnvelope;
		if (old!=NULL) [old dim];
		theEnvelope=lastDeleted;				// set new current envelope
		lastDeleted=NULL;
		[theWindow makeFirstResponder: theEnvelope];
		if (old!=NULL && [theLinkX state]==1) 
			[self broadcastXLimitsOf: old];
		[theSplitView adjustSubviews];
		[theSplitView display];
	}
    return self;
}

- update: sender
{
	int point;
	
	if (theEnvelope!=NULL && theEnvelope!=sender)
		[theEnvelope dim];
	if (theEnvelope!=sender) {
		theEnvelope=sender;
		[theEnvelope highlight];
		[theWindow makeFirstResponder: theEnvelope];
	}
	point=[sender getPoint];
	[thePoint setIntValue: point];
	[theXCoord setFloatValue: [sender getX: point]];
	[theYCoord setFloatValue: [sender getY: point]];
	[theYrCoord setFloatValue: [sender getYr: point]];
	[theSmoothing setFloatValue: [sender getSmoothing: point]];
	[theSmoothSlider setFloatValue: [sender getSmoothing: point]];
	[theXMinCoord setFloatValue: [sender getXMin]];
	[theXMaxCoord setFloatValue: [sender getXMax]];
	[theYMinCoord setFloatValue: [sender getYMin]];
	[theYMaxCoord setFloatValue: [sender getYMax]];
	[theXSnapCoord setFloatValue: [sender getXSnap]];
	[theYSnapCoord setFloatValue: [sender getYSnap]];
	[theStickyPoint setState: [sender getSticky: point]];
	[theGraphType setState: [sender getShowSmooth]];
	return self;
}

- updateCoords: sender at: (int)point
{
	[theXCoord setFloatValue: [sender getX: point]];
	[theYCoord setFloatValue: [sender getY: point]];
	[theYrCoord setFloatValue: [sender getYr: point]];
	return self;	
}

//===================================================================
// Pasteboard interface methods
//===================================================================

- copy:sender
{
	if (theEnvelope!=NULL)
		return [theEnvelope copy: sender];
	return self;
}

- paste:sender
{
	if (theEnvelope!=NULL)
		return [theEnvelope paste: sender];
	return self;
}

//===================================================================
// Messages received from panel buttons and fields to update parameters
//===================================================================

- nextPoint:sender
{
	if (theEnvelope!=NULL) [theEnvelope nextPoint];
	return self;
}

- previousPoint:sender
{
	if (theEnvelope!=NULL) [theEnvelope previousPoint];
	return self;
}

- setPoint:sender
{
	if (theEnvelope!=NULL) [theEnvelope setPointTo: [sender intValue]];
	return self;
}

- setXValue:sender
{
	if (theEnvelope!=NULL) 
		[theEnvelope setXAt: [thePoint intValue] to: [sender floatValue]];
	return self;
}

- setYValue:sender
{
	if (theEnvelope!=NULL) 
		[theEnvelope setYAt: [thePoint intValue] to: [sender floatValue]];
	return self;
}

- setYrValue:sender
{
	if (theEnvelope!=NULL) 
		[theEnvelope setYrAt: [thePoint intValue] to: [sender floatValue]];
	return self;
}

- setSmoothValue:sender
{
	float smooth;
	
	smooth=[sender floatValue];
	smooth=rint(smooth*1000)/1000;
	[theSmoothSlider setFloatValue: smooth];
	if (theEnvelope!=NULL) 
		[theEnvelope setSmoothAt: [thePoint intValue] to: smooth];
	return self;
}

- setSmoothFromSlider:sender
{
	float smooth;
	
	smooth=[sender floatValue];
	smooth=rint(smooth*1000)/1000;
	[theSmoothing setFloatValue: smooth];
	if (theEnvelope!=NULL) 
		[theEnvelope setSmoothAt: [thePoint intValue] to: smooth];
	return self;
}

- broadcastXLimitsOf:envelope
{
	unsigned int i;
	List * envelopes;
	double max, min;
	
	min=[envelope getXMin];
	max=[envelope getXMax];
	envelopes=[theSplitView subviews];
	for (i=0; i<[envelopes count]; i++)
		[[envelopes objectAt: i] setXLimitsTo:min :max];
	return self;
}

- setXMinValue:sender
{
	if (theEnvelope!=NULL) {
		[theEnvelope setXMinTo: [sender floatValue]];
		if ([theLinkX state]==1) 
			[self broadcastXLimitsOf: theEnvelope];
	}
	return self;
}

- setXMaxValue:sender
{
	if (theEnvelope!=NULL) {
		[theEnvelope setXMaxTo: [sender floatValue]];
		if ([theLinkX state]==1) 
			[self broadcastXLimitsOf: theEnvelope];
	}
	return self;
}

- setYMinValue:sender
{
	if (theEnvelope!=NULL) {
		[theEnvelope setYMinTo: [sender floatValue]];
	}
	return self;
}

- setYMaxValue:sender
{
	if (theEnvelope!=NULL) {
		[theEnvelope setYMaxTo: [sender floatValue]];
	}
	return self;
}

- setXSnapValue:sender
{
	if (theEnvelope!=NULL) {
		[theEnvelope setXSnapTo: [sender floatValue]];
	}
	return self;
}

- setYSnapValue:sender
{
	if (theEnvelope!=NULL) {
		[theEnvelope setYSnapTo: [sender floatValue]];
	}
	return self;
}

- setStickyPoint:sender
{
	if (theEnvelope!=NULL) 
		[theEnvelope setStickyAt: [thePoint intValue] To: [sender state]];
	return self;
}

- setGraphType:sender
{
	if (theEnvelope!=NULL) 
		[theEnvelope setShowSmooth: [sender state]];
	return self;
}

- setDrawSegmentsState:sender
{
	if (theEnvelope!=NULL) {
	    if ([theEnvelope getDrawSegments]==-1)
		[theEnvelope setDrawSegments: 0];
	    else
	    	[theEnvelope setDrawSegments: -1];
	}
	return self;
}

- setLinkX:sender
{
	if (theEnvelope!=NULL && [sender state]==1) 
		[self broadcastXLimitsOf: theEnvelope];
	return self;
}

- reScaleLimits:sender;
{
	if (theEnvelope!=NULL) {
		[theEnvelope scaleLimits];
		if ([theLinkX state]==1) 
			[self broadcastXLimitsOf: theEnvelope];
	}
	return self;
}

//===================================================================
// Messages received from the envelope to query for parameters
//===================================================================

- (const char *)getStyle
{
	return [[[theOutputTypes cell] target] selectedItem];
}

@end
